package java8.atguigu.teacher.lambda06.stream01;

import java8.atguigu.lu.l01.Employee;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @program lambda
 * @description:
 * @author: zhanglu
 * @create: 2019-05-26 22:07:00
 *
 * 一、Stream 的三个操作步骤
 *
 * 1、创建Stream
 * 2、中间操作
 * 3、终止操作(终端操作)
 *
 */
//终止操作(终端操作)
public class TestStreamAPI03 {

    List<Employee> employeeList = Arrays.asList(
            new Employee("张1",20,100, Employee.Status.FREE),
            new Employee("张2", 21, 101, Employee.Status.BUSY),
            new Employee("张3", 22, 102, Employee.Status.VOCATION),
            new Employee("张4", 23, 103, Employee.Status.FREE),
            new Employee("张5", 24, 104, Employee.Status.BUSY),
//            new Employee("张6", 25, 105, Employee.Status.VOCATION),
            new Employee("张6", 26, 105, Employee.Status.VOCATION)
    );

    /*
        查找与匹配
        allMatch - 检查是否匹配所有元素
        anyMatch - 检查是否至少匹配一个元素
        noneMatch - 检查是否没有匹配所有元素
        findFirst - 返回第一个元素
        findAny - 返回当前流中的任意元素
        count - 返回流中元素的总个数
        max - 返回流中最大值
        min - 返回流中最小值
     */

    //allMatch、anyMatch、noneMatch、findFirst、findAny
    @Test
    public void test01(){
        //是否全部匹配
        boolean b1 = employeeList.stream().allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b1);

        //是否有一个条件匹配
        boolean b2 = employeeList.stream().anyMatch(e -> e.getStatus().equals(Employee.Status.BUSY));
        System.out.println(b2);

        //是否没有匹配
        boolean b3 = employeeList.stream().noneMatch(e -> e.getStatus().equals("1212"));
        System.out.println(b3);

        //是否没有匹配
        Optional<Employee> op = employeeList.stream()
                .sorted((e1, e2) -> Integer.compare(e2.getAge(), e1.getAge()))
                .findFirst();
        System.out.println(op.get());

        //是否没有匹配
        Optional<Employee> op2 = employeeList.parallelStream()  //并行流
                .filter(e -> e.getStatus().equals(Employee.Status.FREE))
                .findAny();
        System.out.println(op2.get());

    }

    //count、max、min
    @Test
    public void test02(){
        long count = employeeList.stream().count();
        System.out.println(count);

        Optional<Employee> op = employeeList.stream().
                max((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge()));
        System.out.println(op.get());

        Optional<Integer> op2 = employeeList.stream()
                .map(Employee::getAge)
                .min((e1, e2) -> Integer.compare(e2, e1));
        System.out.println(op2.get());
    }


    /*
        归约
        reduce

        map + reduce = 大数据(对数据计算分析)
     */

    @Test
    public void test03(){
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Integer sum = list.stream().reduce(0, (x, y) ->  x + y);
        System.out.println(sum);

        System.out.println("-------------------------------------------");

//        Map<Object,Object> ls =  employeeList.stream().collect(Collectors.toMap(o -> o.getAge(), e -> e));
////        System.out.println(ls);

        employeeList.stream().map(o -> o.getAge()).forEach(System.out::println);

        Optional<Integer> op = employeeList.stream().map(Employee::getAge)
                .reduce(Integer::sum);
        System.out.println(op.get());
    }




    /*
        收集
        collect - 将流转换微其他形式。接收一个Collector接口的实现，用于给Stream中元素做汇总
     */
    @Test
    public void test04(){
        List<String> list = employeeList.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());
        list.stream().forEach(System.out::println);


        System.out.println("-----------------------------------");


        Set<String> set = employeeList.stream()
                .map(Employee::getName)
                .collect(Collectors.toSet());
        set.stream().forEach(System.out::println);


        System.out.println("-----------------------------------");


        Map<String, Employee> map = employeeList.stream()
                .collect(Collectors.toMap(Employee::getName, Employee -> Employee));
        map.forEach((k, v) -> {
            System.out.println(k + " -> " + v);
        });


        System.out.println("-----------------------------------");


        HashSet<String> hashSet = employeeList.stream()
                .map(Employee::getName)
                .collect(Collectors.toCollection(HashSet::new));
        hashSet.stream().forEach(System.out::println);

    }


    @Test
    public void test05(){
        //总数
        Long count = employeeList.stream()
                        .collect(Collectors.counting());
        System.out.println(count);

        //平均值
        Double avg = employeeList.stream()
                .collect(Collectors.averagingInt(Employee::getAge));
        System.out.println(avg);

        //总和
        Integer sum = employeeList.stream()
                .collect(Collectors.summingInt(Employee::getAge));
        System.out.println(sum);

        //最大值
        Optional<Employee> op = employeeList.stream()
                .collect(Collectors.maxBy((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())));
        System.out.println(op.get());

        //最小值
        Optional<Employee> op2 = employeeList.stream()
                .collect(Collectors.minBy((e1, e2) -> Integer.compare(e1.getAge(), e2.getAge())));
        System.out.println(op2.get());

    }

    //分组、分区 <分组条件，数据对象>
    @Test
    public void test06(){
        //按照状态分组
        Map<Employee.Status, List<Employee>> map =  employeeList.stream()
                .collect(Collectors.groupingBy(Employee::getStatus));
        map.forEach((k, v) -> {
            System.out.println(k + " -> " + v);
        });

        System.out.println("------------------------------------");

        //多级分组
        Map<Integer, Map<String, Map<Boolean, List<Employee>>>> collect = employeeList.stream().collect(Collectors.groupingBy(o -> 1, Collectors.groupingBy(o -> "1", Collectors.groupingBy(o -> true))));

        Map<Employee.Status, Map<String, List<Employee>>> map2 =  employeeList.stream()
                .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy(e -> {
                    if(e.getAge() < 21){
                        return "青年";
                    }else if(e.getAge() < 23){
                        return "中年";
                    }else {
                        return "老年";
                    }
                })));

        map2.forEach((k, v) -> {
            System.out.println(k + " -> " + v);
        });

        System.out.println("------------------------------------");

        //分区
        Map<Boolean, List<Employee>> map3 = employeeList.stream()
                .collect(Collectors.partitioningBy(e -> e.getAge() > 22));
        map3.forEach((k, v) -> {
            System.out.println(k + " -> " + v);
        });

        System.out.println("------------------------------------");

        IntSummaryStatistics iss = employeeList.stream()
                .collect(Collectors.summarizingInt(Employee::getAge));
        System.out.println(iss.getMax());
        System.out.println(iss.getAverage());
        System.out.println(iss.getCount());
        System.out.println(iss.getMin());
        System.out.println(iss.getSum());

        System.out.println("------------------------------------");

        //字符串拼接
        String str = employeeList.stream()
                .map(Employee::getName)
                .collect(Collectors.joining(",", "===", "---"));    //中间 首 尾
        System.out.println(str);

    }


}
